/**
 * 
 */
package com.rf.richfitwheel.admin.sys.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.rf.richfitwheel.admin.sys.dao.*;
import com.rf.richfitwheel.admin.sys.model.*;
import com.rf.richfitwheel.admin.sys.vo.UserVO;
import com.rf.richfitwheel.admin.websocket.server.WebSocketServer;
import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.rf.richfitwheel.admin.sys.service.SysMsgStreamService;
import com.rf.richfitwheel.admin.utils.JacksonJsonUtil;
import com.rf.richfitwheel.common.exception.BusinessException;
import com.rf.richfitwheel.common.utils.JsonUtils;
import com.rf.richfitwheel.common.utils.PageUtils;
import com.rf.richfitwheel.common.utils.StringUtils;
import com.rf.richfitwheel.common.utils.UuidUtil;

import net.sf.json.JSONObject;

/**
 * @author hushouquan
 *
 */
@Service("msgStreamService")
public class SysMsgStreamServiceImpl implements SysMsgStreamService {

	private static Logger log = LoggerFactory.getLogger(SysMsgStreamServiceImpl.class);
	
	@Autowired
    private SysMsgStreamMapper msgStreamMapper;
    @Autowired
    private SysMsgDefMapper msgDefMapper;
    @Autowired
    private SqlAdapterMapper sqlAdapterMapper;
    @Autowired
    private OrgMapper orgMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;
    /*@Autowired
    private FWebSocketServices fWebSocketServices;*/
    
	/**
     *  发送消息接口
     * @param params {"senderId":发送用户id,"pageParam":页面参数,"msgCode":消息定义编码,"businessId":业务id,"msgContext":消息内容,"msgContextParam":消息内容参数}
     * @return
     */
	@Override
	@Transactional(rollbackFor = Exception.class)
    public boolean sendMsg(Map<String, Object> params) throws Exception {
		try {
            SysMsgStream msgStream = new SysMsgStream();
            /*if (StringUtils.isNotBlank(params.get("senderId")))
                msgStream.setSenderId(params.get("senderId").toString());
            else
                try {
                    Session session = SecurityUtils.getSubject().getSession();
                    User user = (User) session.getAttribute("userSession");
                    msgStream.setSenderId(user.getStaffId());
                } catch (Exception e) {
                    msgStream.setSenderId("系统");
                }*/
            msgStream.setSendTime(new Date());
            if (StringUtils.isNotBlank(params.get("pageParam"))) {
                msgStream.setPageParam(params.get("pageParam").toString());
            }
            msgStream.setReceiveState("1");//未接收
            if (StringUtils.isNotBlank(params.get("msgCode"))) {
                msgStream.setMsgCode(params.get("msgCode").toString());
            }
            if (StringUtils.isNotBlank(params.get("businessId"))){
                msgStream.setBusinessId(params.get("businessId").toString());
            }
            if (StringUtils.isNotBlank(params.get("msgContext"))) {
                msgStream.setMsgContext(params.get("msgContext").toString());
            } else {
                SysMsgDefExample example = new SysMsgDefExample();
                SysMsgDefExample.Criteria criteria = example.createCriteria();
                criteria.andMsgCodeEqualTo(params.get("msgCode").toString());
                SysMsgDef msgDef = msgDefMapper.selectByExample(example).get(0);
                String msgContext = msgDef.getMsgContext();
                String msgContextParam = msgDef.getMsgContextParam();
                if (params.containsKey("msgContextParam")) {
                    Map paramMap = JsonUtils.parseJSONMap(params.get("msgContextParam").toString());
//                    Map paramMap = JSON.parseObject(JSONObject.toJSONString(params.get("msgContextParam")).replace("\\", "").replace("\"{", "{").replace("}\"", "}"), Map.class);
                    String[] msgContextParams = msgContextParam.split(",");
                    for (String s : msgContextParams){
                        msgContext = msgContext.replaceAll(s, paramMap.get(s).toString());
                }
                }
                msgStream.setMsgContext(msgContext);
                msgStream.setMsgContextParam(params.get("msgContextParam").toString().replace("\\", "")
                        .replace("\"{", "{").replace("}\"", "}"));
            }
            if (StringUtils.isNotBlank(params.get("tenantId"))) {
                msgStream.setTenantId(params.get("tenantId").toString());
            }
            if(msgStream.getTenantId() == null){
                SysMsgDefExample example = new SysMsgDefExample();
                SysMsgDefExample.Criteria criteria = example.createCriteria();
                criteria.andMsgCodeEqualTo(params.get("msgCode").toString());
                SysMsgDef msgDef = msgDefMapper.selectByExample(example).get(0);
                msgStream.setTenantId(msgDef.getTenantId());
            }
            if (StringUtils.isNotBlank(params.get("receiverId"))) {
                msgStream.setReceiverId(params.get("receiverId").toString());
                msgStream.setId(UuidUtil.get32UUID());
                msgStreamMapper.insertSelective(msgStream);//插入流水表
            } else {
                throw new BusinessException("没有设置消息接受人");
            }


            Map beanMap = BeanUtils.describe(msgStream);
            //调用websocket微服务
            if (params.containsKey("msgCode")) {
                String sql = "select page_url from sys_msg_def where msg_code = '" + params.get("msgCode").toString() + "'";
                List<Map<String, Object>> list = sqlAdapterMapper.selectSQL(sql);
                if (list.size() != 0) {
                    beanMap.put("pageUrl", list.get(0).get("page_url"));
                }
            }
            try {
//				fWebSocketServices.pushToWeb(map);
                WebSocketServer.sendInfo(JacksonJsonUtil.objToJson(beanMap),params.get("receiverId").toString());
			} catch (Exception e) {
				log.error("发送消息至websocket失败", e);
			}

            return true;
        } catch (Exception e) {
            throw new BusinessException("发送消息失败", e);
        }
	}

	/**
     * 查询未读消息
     * @param params
     * @return
     */
	@Override
	public PageUtils queryUndealMsg(Map<String, Object> params, UserVO userVO) {
 		PageUtils pageUtils = PageUtils.getPageInfo(params);
        Page<Map<String, Object>> p = PageHelper.startPage(pageUtils.getPage(), pageUtils.getLimit());
        SysMsgStreamExample example = new SysMsgStreamExample();
        SysMsgStreamExample.Criteria criteria = example.createCriteria();
//        if (params.containsKey("msgDefId"))
//            criteria.andMsgDefIdLike(params.get("msgDefId").toString());
//        JSONObject jsonObject = JSONObject.parseObject(params.get("dataForm").toString(),SysMsgStream.class);
        JSONObject msgStream = JSONObject.fromObject(params.get("dataForm").toString());
        Map<String, Object> pram = new HashMap<String, Object>();
        if (msgStream.containsKey("deal") && msgStream.get("deal").toString().equals("true")){
            pram.put("receiveState", "1");
        }
//            criteria.andReceiveStateEqualTo("1");//未接收
        if (StringUtils.isNotBlank(msgStream.get("senderId"))){
            pram.put("senderId", msgStream.get("senderId").toString());
        }
//            criteria.andSenderIdEqualTo(msgStream.get("senderId").toString());
//        if (StringUtils.isNotBlank(msgStream.getReceiverId()))
//        criteria.andReceiverIdEqualTo(user.getStaffId());
        pram.put("receiverId", userVO.getId());
        pram.put("receiverStaffId", userVO.getStaffId());
        if (StringUtils.isNotBlank(msgStream.get("sendTime").toString())) {
            String sendTimeStr = msgStream.get("sendTime").toString();
            pram.put("sendTimeStart", msgStream.get("sendTime").toString() + "00:00:00");
            pram.put("sendTimeEnd", msgStream.get("sendTime").toString() + "23:59:59");
        }
        //指定消息编码
        String msgCode = (String) msgStream.get("msgCode");
        if(StringUtils.isNotBlank(msgCode)){
            String[] msgCodeList = msgCode.split(",");
            pram.put("msgCodeList",msgCodeList);
        }
        if (StringUtils.isNotBlank(msgStream.get("tenantId"))){
            String[] tenantIds = msgStream.get("tenantId").toString().split(",");
            pram.put("tenantId", tenantIds);
        }
        example.setOrderByClause(" send_time desc ");
        pram.put("orderByClause", " receive_state,send_time desc");
//        List<SysMsgStream> list = msgStreamMapper.selectByExample(example);
        List<Map<String, Object>> list = msgStreamMapper.selectMsgStreamPages(pram);
        pageUtils = new PageUtils(p);
        return pageUtils;
	}

	/**
     * 查询消息
     * @param params
     * @return
     */
	@Override
	public PageUtils queryPage(Map<String, Object> params) {
		PageUtils pageUtils = PageUtils.getPageInfo(params);
        Page<Map<String, Object>> p = PageHelper.startPage(pageUtils.getPage(), pageUtils.getLimit());
        SysMsgStreamExample example = new SysMsgStreamExample();
        SysMsgStreamExample.Criteria criteria = example.createCriteria();
//        if (params.containsKey("msgDefId"))
//            criteria.andMsgDefIdLike(params.get("msgDefId").toString());
        JSONObject msgStream = JSONObject.fromObject(params.get("dataForm").toString());
        Map<String, Object> pram = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(msgStream.get("receiveState"))){
            pram.put("receiveState", msgStream.get("receiveState").toString());
//            criteria.andReceiveStateEqualTo(msgStream.get("receiveState").toString());
        }

        if (StringUtils.isNotBlank(msgStream.get("senderName"))) {
            pram.put("senderName", "%" + msgStream.get("senderName").toString() + "%");
        }
        if (StringUtils.isNotBlank(msgStream.get("receiverName"))){
            pram.put("receiverName", "%" + msgStream.get("receiverName").toString() + "%");
        }
        if (StringUtils.isNotBlank(msgStream.get("tenantId"))){
            String[] tenantIds = msgStream.get("tenantId").toString().split(",");
            pram.put("tenantId", tenantIds);
        }
        if (StringUtils.isNotBlank(msgStream.get("sendTime"))) {
            String sendTimeStr = msgStream.get("sendTime").toString();
            pram.put("sendTimeStart", msgStream.get("sendTime").toString() + "00:00:00");
            pram.put("sendTimeEnd", msgStream.get("sendTime").toString() + "23:59:59");
//            Date sendTime = DateUtils.stringToDate(sendTimeStr, "yyyy-MM-dd");
//            criteria.andSendTimeBetween(sendTime, new Date(sendTime.getTime() + (24 * 60 * 60 * 1000 - 1000)));
        }
        //指定消息编码
        String msgCode = (String) msgStream.get("msgCode");
        if(StringUtils.isNotBlank(msgCode)){
            String[] msgCodeList = msgCode.split(",");
            pram.put("msgCodeList",msgCodeList);
        }
//        example.setOrderByClause(" send_time desc ");
        pram.put("orderByClause", "send_time desc");

        List<Map<String, Object>> list = msgStreamMapper.selectMsgStreamPages(pram);
//        List<SysMsgStream> list = msgStreamMapper.selectByExample(example);
        pageUtils = new PageUtils(p);
        return pageUtils;
	}

	/**
     * 主键获取
     * @param id
     * @return
     * @throws Exception
     */
	@Override
	public SysMsgStream selectById(String id) throws Exception {
		return msgStreamMapper.selectByPrimaryKey(id);
	}

	/**
     * 主键获取
     * @param id
     * @return
     * @throws Exception
     */
	@Override
	public SysMsgStream selectMapById(String id) throws Exception {
		return msgStreamMapper.selectMapByPrimaryKey(id);
	}

	/**
     * 新增消息
     * @param sysMsgStream
     */
	@Override
	@Transactional(rollbackFor = Exception.class)
    public void save(SysMsgStream sysMsgStream) {
		if (StringUtils.isBlank(sysMsgStream.getId())){
			sysMsgStream.setId(UuidUtil.get32UUID());
        }
        msgStreamMapper.insert(sysMsgStream);

	}

	/**
     * 更新信息
     * @param sysMsgStream
     */
	@Override
	@Transactional(rollbackFor = Exception.class)
    public void update(SysMsgStream sysMsgStream) {
		msgStreamMapper.updateByPrimaryKey(sysMsgStream);

	}

	/**
     * 删除信息
     * @param ids
     */
	@Override
	@Transactional(rollbackFor = Exception.class)
    public void deleteBatch(String[] ids) {
		for (String id : ids) {
            msgStreamMapper.deleteByPrimaryKey(id);
        }

	}

	/**
     * 获取接收人未读的消息数
     * @param receiverId
     * @return
     */
	@Override
	public int getUndealMsgNum(String receiverId,String tenantId) {
        Map<String, Object> param = new HashMap<>();
        param.put("receiverId", receiverId);
        if (StringUtils.isNotBlank(tenantId)) {
            param.put("tenantId", tenantId.split(","));
        }
		return msgStreamMapper.getUndealMsgNum(param);
	}

	/**
     * 标记为已读
     * @param ids
     */
	@Override
	@Transactional(rollbackFor = Exception.class)
    public void deal(String[] ids) {
		for (String id : ids){
            msgStreamMapper.deal(id);
	}

	}
    
    /**
     * 给下级机构的角色发消息
     *
     * @param orgCode    机构编码
     * @param roleIds    角色id数组
     * @param message    消息内容
     * @param businessId 业务id
     */
    @Override
    public void sendMsgToChildrenOrgRole(String orgCode, String[] roleIds, String message, String businessId) throws Exception{
        OrgExample example = new OrgExample();
        OrgExample.Criteria criteria = example.createCriteria();
        criteria.andOrgCodeEqualTo(orgCode);
        List<Org> orgP = orgMapper.selectByExample(example);
        if(orgP.isEmpty()){
            throw new BusinessException("根据机构编码没有查询到机构信息");
        }
        OrgExample exampleCh = new OrgExample();
        OrgExample.Criteria criteriaCh = exampleCh.createCriteria();
        criteriaCh.andParentIdEqualTo(orgP.get(0).getId());
        List<Org> children = orgMapper.selectByExample(exampleCh);
        List<String> orgIdList = children.stream().map(Org::getId).collect(Collectors.toList());
        UserRoleExample userRoleExample = new UserRoleExample();
        UserRoleExample.Criteria userRoleCriteria = userRoleExample.createCriteria();
        userRoleCriteria.andOrgIdIn(orgIdList);
        userRoleCriteria.andRoleIdIn(Arrays.asList(roleIds));
        List<UserRole> userRoleList = userRoleMapper.selectByExample(userRoleExample);
        for(UserRole e : userRoleList){
            Map<String, Object> params = new HashMap<>();
            params.put("receiverId", e.getUserId());
            params.put("pageParam", null);
            params.put("msgCode", "common");
            params.put("businessId", businessId);
            params.put("msgContext", message);
            params.put("msgContextParam", null);
            sendMsg(params);
        }
    }
    
}
